package com.example.documentconvertor.service.impl;

import com.example.documentconvertor.service.IndexService;
import com.example.documentconvertor.util.Utils;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.spire.pdf.FileFormat;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.graphics.PdfImageType;
import com.spire.pdf.widget.PdfPageCollection;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;

@Service
public class IndexServiceImpl implements IndexService {

    private static final String PDFPath = "\\files\\pdf\\";

    private static final String WORDPath = "\\files\\word\\";

    private static final String ImgPath = "\\files\\img\\";

    private static final String otherPath = "\\files\\other\\";

    private static final String splitName = "split_";

    private static final String rootPath = Utils.getRootPath();

    @Override
    public Map<String, Object> fileUpload(MultipartFile file, String type) {
        Map<String,Object> result = new HashMap<>();
        if(file.isEmpty()){
            result.put("result",false);
            return result;
        }
        String docStorePath = rootPath;
        String fileName = file.getOriginalFilename();
        assert fileName != null;
        String simpleName = fileName.substring(0, fileName.lastIndexOf("."));
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        String path;
        Random random = new Random();
        String name = simpleName+"_"+random.nextInt();
        if(type.equals("1") || type.equals("2")){
            path=PDFPath;
        }else if(type.equals("3")){
            path=WORDPath;
        }else {
            path=otherPath;
        }
        try {
            File upload = new File(docStorePath,path+name+suffix);
            if(!upload.exists()) {
                upload.mkdirs();
            }
            file.transferTo(upload); //保存文件
            result.put("result",true);
            result.put("originalName",name);
            return result;
        } catch (IllegalStateException | IOException e) {
            e.printStackTrace();
            result.put("result",false);
            return result;
        }
    }

    @Override
    public Map<String, Object> pdfToWord(String originalName) {
        Map<String,Object> result = new HashMap<>();
        boolean success = false;
        //pdf文件路径
        String pdfPath = rootPath+PDFPath+originalName+".pdf";
        PdfDocument pdfDocument = new PdfDocument();
        pdfDocument.loadFromFile(pdfPath);
        PdfPageCollection num = pdfDocument.getPages();
        //如果pdf的页数小于11，那么直接进行转化
        if (num.getCount() <= 10) {
            //生成的word的文件路径
            String wordPath = rootPath+WORDPath+originalName+".docx";
            pdfDocument.saveToFile(wordPath, com.spire.pdf.FileFormat.DOCX);
            success=true;
        }else{ //否则输入的页数比较多(免费版只能处理10页)，就开始进行切分再转化，每10页分一次
            Utils.spitPdf(num.getCount(),pdfDocument,rootPath+PDFPath+splitName+originalName+"\\");

            File[] fs = Utils.getSplitFiles(rootPath+PDFPath+splitName+originalName+"\\");
            for (File f : fs) {
                PdfDocument sonpdf = new PdfDocument();
                sonpdf.loadFromFile(f.getAbsolutePath());
                //单个转换word
                sonpdf.saveToFile(rootPath + WORDPath + splitName + originalName + "\\" + f.getName().substring(0, f.getName().length() - 4) + ".docx", FileFormat.DOCX);
            }
            //再合并word
            success = Utils.mergeWordDocument(rootPath+WORDPath+splitName+originalName+"\\", rootPath+WORDPath+originalName+".docx");
        }
        result.put("result",success);
        result.put("targetName",originalName.substring(0,originalName.lastIndexOf("_"))+".docx");
        Utils.clearFiles(rootPath+PDFPath+splitName+originalName+"\\");
        Utils.clearFiles(rootPath+WORDPath+splitName+originalName+"\\");
        return result;
    }



    @Override
    public Map<String, Object> wordToPdf(String originalName) {
        String sfileName = rootPath+WORDPath+originalName; //待转word文件
        //确定word是doc还是docx
        if(new File(rootPath+WORDPath+originalName+".docx").exists()){
            sfileName = sfileName+".docx";
        }else {
            sfileName = sfileName+".doc";
        }
        String toFileName = rootPath+PDFPath+originalName+".pdf"; //pdf保存路径
        //初始化
        Utils.wordInit();
        //不打开WORD复制
        Utils.wordDoc = Dispatch.invoke(Utils.document,"Open",Dispatch.Method,new Object[] {
                sfileName, new Variant(false),new Variant(true) }, new int[1]).toDispatch();
        File tofile = new File(toFileName);
        if (tofile.exists()) {
            tofile.delete();
        }
        //Dispatch.call(Utils.word, "Run", new Variant("finalStatewordToPdf")); 定义宏
        Dispatch.invoke(Utils.wordDoc, "SaveAs", Dispatch.Method, new Object[] {
                toFileName, new Variant(17) }, new int[1]);
        //关闭资源
        Utils.release();
        //返回结果
        Map<String,Object> result = new HashMap<>();
        result.put("result",true);
        result.put("targetName",originalName.substring(0,originalName.lastIndexOf("_"))+".pdf");
        return result;
    }

    @Override
    public Map<String, Object> pdfToImg(String originalName) {
        Map<String,Object> result = new HashMap<>();
        List<File> files = new ArrayList<>();
        //创建Document对象
        PdfDocument PDF = new PdfDocument();
        //加载pdf文档
        PDF.loadFromFile(rootPath+PDFPath+originalName+".pdf");
        PdfPageCollection num = PDF.getPages();
        //如果pdf的页数小于11，那么直接进行转化
        if(num.getCount() <= 10){
            for (int i = 0; i < PDF.getPages().getCount(); i++) {
                BufferedImage image = PDF.saveAsImage(i, PdfImageType.Bitmap);
                File file = new File(rootPath+ImgPath+originalName +"\\"+ originalName.substring(0,originalName.lastIndexOf("_")) + "（" + i + "）" + ".png");
                if(!file.exists()) {
                    file.mkdirs();
                }
                files.add(file);
                try {
                    ImageIO.write(image, "PNG", file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }else{ //否则输入的页数比较多(免费版只能处理10页)，就开始进行切分再转化
           // 第一步：将其进行切分,每页一张pdf
            PDF.split(rootPath+PDFPath+splitName+originalName+"\\"+"$division{0}.pdf",0);
            File[] fs = Utils.getSplitFiles(rootPath+PDFPath+splitName+originalName+"\\");
            for (int i=0; i< fs.length; i++) {
                PdfDocument sonpdf = new PdfDocument();
                sonpdf.loadFromFile(rootPath+PDFPath+splitName+originalName+"\\"+"$division"+i+".pdf");
                //单个转换图片
                BufferedImage image = PDF.saveAsImage(0, PdfImageType.Bitmap);
                File file = new File(rootPath+ImgPath+originalName +"\\"+ originalName.substring(0,originalName.lastIndexOf("_")) + "（" + i + "）" + ".png");
                if(!file.exists()) {
                    file.mkdirs();
                }
                files.add(file);
                try {
                    ImageIO.write(image, "PNG", file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        PDF.close();
        //打成压缩包
        try {
            OutputStream os = new FileOutputStream(rootPath+ImgPath+originalName+".zip");
            Utils.toZip(files,os);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Utils.clearFiles(rootPath+PDFPath+splitName+originalName+"\\");
        Utils.clearFiles(rootPath+ImgPath+originalName+"\\");
        result.put("result",true);
        result.put("targetName",originalName.substring(0,originalName.lastIndexOf("_"))+".zip（图片压缩包）");
        return result;
    }

    @Override
    public void download(String name, String type, HttpServletResponse response) {
        String dir = "";
        String suffix = "";
        switch (type) {
            case "1":  //pdf转word 去word的目录下载
                dir = WORDPath;
                suffix = ".docx";
                name = name + suffix;
                break;
            case "2":  //pdf转图片，打成了压缩包 去img的目录下载
                dir = ImgPath;
                suffix = ".zip";
                name = name + suffix;
                break;
            case "3":  //word转pdf 去pdf的目录下载
                dir = PDFPath;
                suffix = ".pdf";
                name = name + suffix;
                break;
        }
        response.setContentType("application/octet-stream");
        try {
            response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(name.substring(0,name.lastIndexOf("_"))+suffix, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        byte[] buff = new byte[1024];
        //创建缓冲输入流
        BufferedInputStream bis = null;
        OutputStream outputStream = null;

        try {
            outputStream = response.getOutputStream();

            //这个路径为待下载文件的路径
            bis = new BufferedInputStream(new FileInputStream(new File(rootPath+dir + name )));
            int read = bis.read(buff);

            //通过while循环写入到指定了的文件夹中
            while (read != -1) {
                outputStream.write(buff, 0, buff.length);
                outputStream.flush();
                read = bis.read(buff);
            }
        } catch ( IOException e ) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void delete(String originalName) {
        Utils.deleteFile(new File(rootPath+WORDPath+originalName+".docx"));
        Utils.deleteFile(new File(rootPath+PDFPath+originalName+".pdf"));
        Utils.deleteFile(new File(rootPath+ImgPath+originalName+".zip"));
    }

}
